package com.styletransfer.mapper;

import com.styletransfer.mapper.provider.StyleSqlProvider;
import com.styletransfer.model.Style;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 风格Mapper接口
 *
 * 这个接口定义了与风格表相关的数据库操作方法。
 * 使用MyBatis的注解方式，可以直接在接口方法上编写SQL语句。
 */
@Mapper
public interface StyleMapper {

    /**
     * 根据ID查询风格
     *
     * @param id 风格ID
     * @return 风格对象
     */
    @Select("SELECT * FROM style WHERE id = #{id}")
    Style findById(Long id);

    /**
     * 根据ID数组批量查询风格
     *
     * @param ids 风格ID数组
     * @return 风格对象列表
     */
    @Select("<script>SELECT * FROM style WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    List<Style> findByIds(@Param("ids") List<Long> ids);

    /**
     * 插入风格
     *
     * @param style 风格对象
     * @return 影响的行数
     */
    @Insert("INSERT INTO style(name, description, coverImage, previewImage, creatorId, type, category, " +
            "useCount, likeCount, favoriteCount, createTime, updateTime, status) " +
            "VALUES(#{name}, #{description}, #{coverImage}, #{previewImage}, #{creatorId}, #{type}, #{category}, " +
            "#{useCount}, #{likeCount}, #{favoriteCount}, #{createTime}, #{updateTime}, #{status})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Style style);

    /**
     * 更新风格
     *
     * @param style 风格对象
     * @return 影响的行数
     */
    @Update("UPDATE style SET name = #{name}, description = #{description}, coverImage = #{coverImage}, " +
            "previewImage = #{previewImage}, category = #{category}, updateTime = #{updateTime} " +
            "WHERE id = #{id}")
    int update(Style style);

    /**
     * 更新风格状态
     *
     * @param id 风格ID
     * @param status 新状态
     * @return 影响的行数
     */
    @Update("UPDATE style SET status = #{status}, updateTime = NOW() WHERE id = #{id}")
    int updateStatus(@Param("id") Long id, @Param("status") Integer status);

    /**
     * 增加风格使用次数
     *
     * @param id 风格ID
     * @return 影响的行数
     */
    @Update("UPDATE style SET useCount = useCount + 1, updateTime = NOW() WHERE id = #{id}")
    int incrementUseCount(Long id);

    /**
     * 增加风格点赞数
     *
     * @param id 风格ID
     * @return 影响的行数
     */
    @Update("UPDATE style SET likeCount = likeCount + 1, updateTime = NOW() WHERE id = #{id}")
    int incrementLikeCount(Long id);

    /**
     * 减少风格点赞数
     *
     * @param id 风格ID
     * @return 影响的行数
     */
    @Update("UPDATE style SET likeCount = GREATEST(likeCount - 1, 0), updateTime = NOW() WHERE id = #{id}")
    int decrementLikeCount(Long id);

    /**
     * 增加风格收藏数
     *
     * @param id 风格ID
     * @return 影响的行数
     */
    @Update("UPDATE style SET favoriteCount = favoriteCount + 1, updateTime = NOW() WHERE id = #{id}")
    int incrementFavoriteCount(Long id);

    /**
     * 减少风格收藏数
     *
     * @param id 风格ID
     * @return 影响的行数
     */
    @Update("UPDATE style SET favoriteCount = GREATEST(favoriteCount - 1, 0), updateTime = NOW() WHERE id = #{id}")
    int decrementFavoriteCount(Long id);

    /**
     * 查询所有风格
     *
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 ORDER BY id DESC")
    List<Style> findAll();

    /**
     * 查询官方风格
     *
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 AND type = 1 ORDER BY id DESC")
    List<Style> findOfficial();

    /**
     * 查询用户创建的风格
     *
     * @param creatorId 创建者ID
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 AND creatorId = #{creatorId} ORDER BY id DESC")
    List<Style> findByCreator(Long creatorId);

    /**
     * 查询热门风格
     *
     * @param limit 限制数
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 ORDER BY useCount DESC LIMIT #{limit}")
    List<Style> findHot(Integer limit);

    /**
     * 根据分类ID查询风格列表
     *
     * @param categoryId 分类ID
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE category = #{categoryId} AND status = 1")
    List<Style> findByCategory(Long categoryId);

    /**
     * 查询最新风格
     *
     * @param limit 限制数量
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 ORDER BY createTime DESC LIMIT #{limit}")
    List<Style> findLatest(Integer limit);

    /**
     * 根据标签查询风格
     *
     * @param tagId 标签ID
     * @return 风格列表
     */
    @Select("SELECT s.* FROM style s " +
            "INNER JOIN style_tag st ON s.id = st.styleId " +
            "WHERE s.status = 1 AND st.tagId = #{tagId} " +
            "ORDER BY s.id DESC")
    List<Style> findByTag(Long tagId);

    /**
     * 查询公开风格（用户创建的正常状态风格）
     *
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 AND type = 2 ORDER BY id DESC")
    List<Style> findPublic();

    /**
     * 搜索风格
     *
     * @param keyword 关键词
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 AND (name LIKE CONCAT('%', #{keyword}, '%') OR description LIKE CONCAT('%', #{keyword}, '%')) ORDER BY id DESC")
    List<Style> search(String keyword);

    /**
     * 分页查询风格
     *
     * @param offset 偏移量
     * @param limit 限制数
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE status = 1 ORDER BY id DESC LIMIT #{offset}, #{limit}")
    List<Style> findByPage(@Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 分页查询风格（支持多条件）
     *
     * @param offset 偏移量
     * @param limit 限制数
     * @param keyword 关键词
     * @param tagId 标签ID
     * @param categoryId 分类ID
     * @param userId 用户ID
     * @param orderBy 排序字段
     * @param orderType 排序类型
     * @return 风格列表
     */
    @SelectProvider(type = StyleSqlProvider.class, method = "findByPageWithConditions")
    List<Style> findByPageWithConditions(
            @Param("offset") Integer offset,
            @Param("limit") Integer limit,
            @Param("keyword") String keyword,
            @Param("tagId") Long tagId,
            @Param("categoryId") Long categoryId,
            @Param("userId") Long userId,
            @Param("orderBy") String orderBy,
            @Param("orderType") String orderType);

    /**
     * 统计风格总数（支持多条件）
     *
     * @param keyword 关键词
     * @param tagId 标签ID
     * @param categoryId 分类ID
     * @param userId 用户ID
     * @return 风格总数
     */
    @SelectProvider(type = StyleSqlProvider.class, method = "countWithConditions")
    Long countWithConditions(
            @Param("keyword") String keyword,
            @Param("tagId") Long tagId,
            @Param("categoryId") Long categoryId,
            @Param("userId") Long userId);

    /**
     * 统计风格总数
     *
     * @return 风格总数
     */
    @Select("SELECT COUNT(*) FROM style WHERE status = 1")
    Long count();

    /**
     * 查询相关风格
     *
     * @param styleId 风格ID
     * @param type 风格类型
     * @param limit 限制数量
     * @return 风格列表
     */
    @Select("SELECT * FROM style WHERE id != #{styleId} AND status = 1 AND type = #{type} ORDER BY RAND() LIMIT #{limit}")
    List<Style> findRelated(@Param("styleId") Long styleId, @Param("type") Integer type, @Param("limit") Integer limit);
}
